﻿#include <afxwin.h>
#include <iostream>
using namespace std;

// 运行时类信息机制的使用
/* 类必须派生自CObject
*  类内必须添加声明宏 DECLARE_DYNAMIC(类名)
*  类外必须添加实现宏 IMPLEMENT_DYNAMIC(类名，父类名)
*  当一个类具备以上三个条件后,CObject::IsKindOf函数就可以正确判断对象是否属于某个类
*/

// 数据结构    (宏展开的静态变量的类型) 
/* struct CRuntimeClass
 { 
    LPCSTR m_lpszClassName;     类名称
	int m_nObjectSize;			类大小
	UINT m_wSchema;				类版本  OxFFFF
	CObject* (PASCAL* m_pfnCreateObject)();    动态创建机制使用，这里为NULL
	CRuntimeClass* m_pBaseClass;     父类宏展开静态变量地址
	CRuntimeClass* m_pNextClass;     不使用为NULL 
	const AFX_CLASSINIT* m_pClassInit;    不使用为NULL
 }*/

// RUNTIME_CLASS(theClass)=>&theClass::classtheClass
//  获取theClass这个类的静态变量的地址

// 执行过程
/* 利用对象(yellowdog)的地址调用宏展开的虚函数GetRuntimeClass()获取本类静态变量的地址(链表头)
*  利用本类静态变量的地址(链表头)和目标进行比对
*  如果相通，证明对象属于这个类
*  如果不相同获取链表的下一个节点(父类静态变量地址)循环比对，只要有一次相通也能证明属于这个类
*  循环结束后一次也没比对成功则证明对象不属于这个类
*/


class CAnimail :public CObject
{
	DECLARE_DYNAMIC(CAnimail)
};

IMPLEMENT_DYNAMIC(CAnimail,CObject)

class CDog :public CAnimail
{
	//DECLARE_DYNAMIC(CDog)
	static const CRuntimeClass classCDog;
	virtual CRuntimeClass* GetRuntimeClass() const; 
};

//IMPLEMENT_DYNAMIC(CDog, CAnimail)
//IMPLEMENT_RUNTIMECLASS(CDog, CAnimail, 0xFFFF, NULL, NULL)

AFX_COMDAT const CRuntimeClass CDog::classCDog =
{ 
	"CDog",					// 类名称
	sizeof(class CDog),     // 类大小
	0xFFFF,					// 类版本  OxFFFF
	NULL,					// 动态创建机制使用，这里为NULL
	//RUNTIME_CLASS(CAnimail),   //父类宏展开静态变量地址
	((CRuntimeClass*)(&CAnimail::classCAnimail)),  
	NULL, 
	NULL
}; 

CRuntimeClass* CDog::GetRuntimeClass() const
{ 
	//return RUNTIME_CLASS(CDog);
	return ((CRuntimeClass*)(&CDog::classCDog));
}

int main()
{
	CDog yellowdog;
	if (yellowdog.IsKindOf(RUNTIME_CLASS(CObject)))
		cout << "yellowdog is CObject" << endl;
	else
		cout << "yellowdog is not CObject" << endl;


	return 0;
}